package io.sundial.core.lifecycle;

import io.sundial.core.Atomic;
import io.sundial.core.AtomicVTCommand;
import io.sundial.core.context.Context;
import io.sundial.core.lifecycle.exception.DestroyingException;
import io.sundial.core.lifecycle.exception.InitializingException;

import java.util.concurrent.atomic.AtomicReference;

import static io.sundial.core.lifecycle.Lifecycle.State.*;

/**
 * 有状态的
 *
 * @author Payne 646742615@qq.com
 * 2018/12/20 20:35
 */
public abstract class Stateful extends Atomic implements Lifecycle {
    private final AtomicReference<State> state = new AtomicReference<>(NONE);
    protected Context context;

    @Override
    public State state() {
        return state.get();
    }

    @Override
    public void initialize(final Context context) throws InitializingException {
        doWritingCommand(new AtomicVTCommand<InitializingException>() {
            @Override
            public void run() throws InitializingException {
                if (!state.compareAndSet(NONE, INITIALIZING)) {
                    return;
                }
                Stateful.this.context = context;
                initializing(context);
                state.set(INITIALIZED);
            }
        });
    }

    protected void initializing(Context context) throws InitializingException {

    }

    @Override
    public void destroy() throws DestroyingException {
        doWritingCommand(new AtomicVTCommand<DestroyingException>() {
            @Override
            public void run() throws DestroyingException {
                if (!state.compareAndSet(INITIALIZED, DESTROYING)) {
                    return;
                }
                destroying();
                state.set(DESTROYED);
            }
        });
    }

    protected void destroying() throws DestroyingException {

    }

}
